package com.milkshopbackend.milkshop.Service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.milkshopbackend.milkshop.Service.OrderService;
import com.milkshopbackend.milkshop.Service.ProductStatsService;
import com.milkshopbackend.milkshop.entity.*;
import com.milkshopbackend.milkshop.enums.OrderStatus;
import com.milkshopbackend.milkshop.mapper.*;
import com.milkshopbackend.milkshop.util.SecurityUtils;
import com.milkshopbackend.milkshop.util.RedisLockUtil;
import com.milkshopbackend.milkshop.common.RedisConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;

@Slf4j
@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    
    @Autowired
    private OrderItemMapper orderItemMapper;
    
    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private OrderPaymentMapper orderPaymentMapper;

    @Autowired
    private ReviewMapper reviewMapper;

    @Autowired
    private ProductStatsService productStatsService;

    @Resource
    private RedisLockUtil redisLockUtil;

    @Override
    @Transactional
    public Order createOrder(OrderCreateDTO orderDTO) {
        Long userId = SecurityUtils.getCurrentUserId();
        String lockKey = "order:lock:user:" + userId;
        String lockId = redisLockUtil.lock(lockKey, 10); // 10秒锁
        if (lockId == null) {
            throw new RuntimeException("操作过快，请稍后再试");
        }
        try {
            // 1. 校验订单项
            if (orderDTO.getOrderItems() == null || orderDTO.getOrderItems().isEmpty()) {
                throw new RuntimeException("订单项不能为空");
            }

            // 2. 计算订单总金额
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (OrderItemDTO itemDTO : orderDTO.getOrderItems()) {
                if (itemDTO == null) {
                    throw new RuntimeException("订单项不能为空");
                }
                if (itemDTO.getProductId() == null) {
                    throw new RuntimeException("产品ID不能为空");
                }
                if (itemDTO.getQuantity() == null) {
                    throw new RuntimeException("数量不能为空");
                }
                Product product = productMapper.selectById(itemDTO.getProductId());
                if (product == null) {
                    throw new RuntimeException("商品不存在，ID: " + itemDTO.getProductId());
                }
                if (product.getPrice() == null) {
                    throw new RuntimeException("商品价格未设置，ID: " + itemDTO.getProductId());
                }
                BigDecimal price = product.getPrice();
                Integer quantity = itemDTO.getQuantity();
                totalAmount = totalAmount.add(price.multiply(new BigDecimal(quantity)));
            }

            // 3. 创建订单对象
            Order order = Order.createFromDTO(orderDTO, userId, generateOrderNo());
            // 4. 设置总金额
            order.setTotalAmount(totalAmount);
            // 5. 保存订单
            save(order);
            return order;
        } finally {
            redisLockUtil.unlock(lockKey, lockId);
        }
    }
    
    @Override
    public Order getOrderById(Long orderId) {
        // 获取当前用户ID
        Long userId = SecurityUtils.getCurrentUserId();
        
        // 查询订单
        Order order = this.lambdaQuery()
                .eq(Order::getId, orderId)
                .eq(Order::getUserId, userId)
                .one();
        
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 补充orderItems
        List<OrderItem> items = orderItemMapper.selectList(
            new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderId, order.getId())
        );
        order.setOrderItems(items != null ? items : new ArrayList<>());
        return order;
    }
    
    @Override
    @Transactional
    public void cancelOrder(Long orderId,String reason) {
        Order order = getById(orderId);
        if (order != null && order.getStatus().equals(OrderStatus.PENDING_PAYMENT.getCode())) {
            order.setStatus(OrderStatus.CANCELLED.getCode());
            updateById(order);
        } else {
            throw new RuntimeException("订单不存在或状态不允许取消");
        }
    }

    @Override
    public Page<Order> listOrders(OrderQueryDTO queryDTO) {
        Page<Order> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();

        // 只查当前用户订单
        Long userId = SecurityUtils.getCurrentUserId();
        wrapper.eq(Order::getUserId, userId);

        // 按状态筛选
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Order::getStatus, queryDTO.getStatus());
        }

        wrapper.orderByDesc(Order::getCreateTime);
        Page<Order> result = page(page, wrapper);
        // 为每个订单补充orderItems字段，保证非null
        for (Order order : result.getRecords()) {
            List<OrderItem> items = orderItemMapper.selectList(
                new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderId, order.getId())
            );
            order.setOrderItems(items != null ? items : new ArrayList<>());
        }
        return result;
    }

    @Override
    @Transactional
    public void payOrder(Long orderId, Integer paymentMethod) {
        Order order = getById(orderId);
        if (order != null && order.getStatus().equals(OrderStatus.PENDING_PAYMENT.getCode())) {
            order.setStatus(OrderStatus.PAID.getCode());
            updateById(order);
        } else {
            throw new RuntimeException("订单不存在或状态不允许支付");
        }
    }

    @Override
    @Transactional
    public void shipOrder(Long orderId, String trackingNo, String shippingCompany) {

        // 查询订单
        Order order = this.getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 检查订单状态
        if (order.getStatus() != OrderStatus.PAID.getCode()) {
            throw new RuntimeException("订单状态不正确");
        }

        // 更新订单状态为已发货
        order.setStatus(OrderStatus.SHIPPED.getCode());
        this.updateById(order);
    }

    @Override
    @Transactional
    public void confirmOrder(Long orderId) {

        // 获取当前用户ID
        Long userId = SecurityUtils.getCurrentUserId();

        // 查询订单
        Order order = this.lambdaQuery()
                .eq(Order::getId, orderId)
                .eq(Order::getUserId, userId)
                .one();

        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 检查订单状态
        if (order.getStatus() != OrderStatus.SHIPPED.getCode()) {
            throw new RuntimeException("订单状态不正确");
        }

        // 更新订单状态为已完成
        order.setStatus(OrderStatus.COMPLETED.getCode());
        this.updateById(order);
        // 新增：订单完成时增加商品销量
        productStatsService.updateProductSalesByOrder(orderId);
    }

    @Override
    @Transactional
    public void reviewOrder(Long orderId, OrderReviewDTO reviewDTO) {
        Order order = getById(orderId);
        if (order != null && order.getStatus().equals(OrderStatus.COMPLETED.getCode())) {
            // TODO: 保存评价信息
        } else {
            throw new RuntimeException("订单不存在或状态不允许评价");
        }
    }

    @Override
    @Transactional
    public void completeOrder(Long orderId) {
        Order order = getById(orderId);
        if (order != null && order.getStatus().equals(OrderStatus.PAID.getCode())) {
            order.setStatus(OrderStatus.COMPLETED.getCode());
            updateById(order);
            // 新增：订单完成时增加商品销量
            productStatsService.updateProductSalesByOrder(orderId);
        } else {
            throw new RuntimeException("订单不存在或状态不允许完成");
        }
    }

    @Override
    public Order getOrderByOrderNo(String orderNo) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getOrderNo, orderNo);
        return getOne(wrapper);
    }

    @Override
    @Transactional
    public void deliverOrder(Long orderId) {
        Order order = getById(orderId);
        if (order != null && order.getStatus().equals(OrderStatus.PAID.getCode())) {
            order.setStatus(OrderStatus.SHIPPED.getCode());
            updateById(order);
        } else {
            throw new RuntimeException("订单不存在或状态不允许发货");
        }
    }

    @Override
    @Transactional
    public void receiveOrder(Long orderId) {
        Order order = getById(orderId);
        if (order != null && order.getStatus().equals(OrderStatus.SHIPPED.getCode())) {
            order.setStatus(OrderStatus.COMPLETED.getCode());
            updateById(order);
        } else {
            throw new RuntimeException("订单不存在或状态不允许收货");
        }
    }

    /**
     * 生成订单编号
     * 格式：年月日时分秒 + 6位随机数
     */
    private String generateOrderNo() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
                + String.format("%06d", (int)(Math.random() * 1000000));
    }

    /**
     * 生成支付流水号
     */
    private String generatePaymentNo() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
                + String.format("%06d", (int)(Math.random() * 1000000));
    }
}
